﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tracy.DataModel;
using SharedLib.XmlDataModel;

namespace TracyGUI.UIComponent
{
    abstract class TabPageGeneric<T> : TabPage where T : XmlDataModelWithAttributesAndID
    {
        protected EnhancedListView _listViewItems;

        public EnhancedListView ListViewItems
        {
            get { return _listViewItems; }
        }

        internal TabPageGeneric(string name, string text, ContextMenuStrip contextMenu)
        {
            this.Name = name;
            this.Text = text;
            InitListView(contextMenu);
        }

        protected ColumnHeader AddColumn(string name, int columnType = ListViewColumnSorter.COLUMN_TYPE_TEXT)
        {
            if (columnType != ListViewColumnSorter.COLUMN_TYPE_TEXT)
            {
                int index = _listViewItems.Columns.Count;
                _listViewItems.ColumnTypeMapping.Add(index, columnType);
            }
            ColumnHeader rtn = _listViewItems.Columns.Add(name);
            rtn.Name = name;
            return rtn;
        }

        private void InitListView(ContextMenuStrip contextMenu)
        {
            _listViewItems = new EnhancedListView();

            InitColumns();

            //Styles
            _listViewItems.View = View.Details;
            _listViewItems.Dock = DockStyle.Fill;
            _listViewItems.ContextMenuStrip = contextMenu;

            this.Controls.Add(_listViewItems);
        }

        protected abstract void InitColumns();

        internal void LoadDataItemsToListView(List<T> dataItems, bool clearView = true)
        {
            if (clearView) 
            {
                ClearListView();
            }

            foreach (T item in dataItems)
            {
                AddDataItemToListView(item);
            }
        }

        internal void AddDataItemToListView(T dataItem)
        {
            if (IsVisiable(dataItem))
            {
                ListViewItem lvItem = CreateListViewItem(dataItem);
                _listViewItems.Items.Insert(0, lvItem);
            }
        }

        protected virtual bool IsVisiable(T dataItem)
        {
            return true;
        }
        protected abstract ListViewItem CreateListViewItem(T dataItem);

        protected void AddSubListViewItem(ListViewItem lvItem, string name, string text)
        {
            ListViewItem.ListViewSubItem lvSubItem = new ListViewItem.ListViewSubItem(lvItem, text);
            lvSubItem.Name = name;
            lvItem.SubItems.Add(lvSubItem);
        }

        internal void ClearListView()
        {
            _listViewItems.Items.Clear();
        }

        internal void RemoveDataItems(List<T> dataItemsToRemove)
        {
            foreach (T item in dataItemsToRemove)
            {
                if (_listViewItems.Items.ContainsKey(item.ID))
                {
                    _listViewItems.Items.RemoveByKey(item.ID);
                }
                else
                {
                }

            }
        }

        internal List<T> GetSelectedDataItems()
        {
            List<T> rtn = new List<T>();
            foreach (ListViewItem item in _listViewItems.SelectedItems)
            {
                T dataItem = item.Tag as T;
                if (dataItem != null && !rtn.Contains(dataItem))
                {
                    rtn.Add(dataItem);
                }
            }
            return rtn;
        }

        internal void UpdateDataItem(T dataItem)
        {
            if (dataItem != null)
            {
                if (_listViewItems.Items.ContainsKey(dataItem.ID))
                {
                    ListViewItem lvItem = _listViewItems.Items[dataItem.ID];
                    lvItem.Tag = dataItem;
                    UpdateListViewItem(lvItem, dataItem);
                }
            }
        }

        protected abstract void UpdateListViewItem(ListViewItem lvItem, T dataItem);
    }
}
